import subprocess
import time

import allure
from pywinauto import Application

from constants.constant_config import APP_PATH, APP_DIR, MAIN_WINDOW
from utils.exception import ControlNotFoundException


class Program:

    def __init__(self, app_path=APP_PATH, app_dir=APP_DIR, main_window_title=MAIN_WINDOW):
        self.app_path = app_path
        self.app_dir = app_dir
        self.main_window_title = main_window_title

    @allure.title("启动程序")
    def start_program(self):
        subprocess.Popen([self.app_path], cwd=self.app_dir)

    @allure.title("关闭程序")
    def close_program(self):
        app = Application(backend="uia").connect(title_re=self.main_window_title, timeout=20)
        app.kill()

    @allure.title("链接程序")
    def connect_program(self):
        while True:
            try:
                self.app = Application(backend="uia").connect(title_re=self.main_window_title, timeout=20)
                print(f"链接：{self.main_window_title} 程序成功")
                return self.app
            except TimeoutError:
                print("连接失败，请检查地址是否配置正确")
                time.sleep(1)

    @allure.title("操作窗口内容")
    def operation_window(self, params, win_name=None):
        if win_name is None:
            win_name = self.main_window_title

        win = self.app.window(title=win_name)
        print(f"成功获取操作窗口：{win_name}")

        for item in params.get('input', []):
            target_control = win.child_window(title=item[0])
            if target_control.exists():
                self.set_text(target_control, item[1])
            else:
                print(f"未找到目标控件，参数为：{item[0]}")
                raise ControlNotFoundException("未找到控件")

        for item in params.get('click', []):
            try:
                win.child_window(title=item, found_index=0).click_input()
            except ControlNotFoundException("未找到控件"):
                print(f"未找到目标控件，参数为：{item}")
        return win_name

    @allure.title("查找到下一个控件")
    def set_text(self, control, text):
        siblings = control.parent().children()
        for i, sibling in enumerate(siblings):
            if sibling == control and i < len(siblings) - 1:
                sibling_edit = siblings[i + 1].set_text(text)
                return sibling_edit
        return None

